package Presenter;


import TCPFile.TCPReceive;

import chatsystemTDa2.*;
import gui.GUIFacade;
import java.io.File;
import java.io.IOException;
import static java.net.InetAddress.getLocalHost;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import model.LocalUser;
import model.Model;
import model.RemoteUser;
import ni.NIFacade;

/**
 *
 * @author julien
 */
public class Presenter implements FromGui, FromNI {
    
    private Model model;
    private GUIFacade gui;
    private NIFacade n;
    private LinkedList<File> waitToSend;
    
    public Presenter() throws SocketException, InterruptedException, UnknownHostException {
        this.gui = new GUIFacade(this);
        n = new NIFacade(this);
        waitToSend = new LinkedList();
    }
    
    public Model getModel(){
        return model;
    }
    
     public File fileWaiting(String f){
        File aux = null;
        for(File j : waitToSend){
            if(j.getName().equals(f))
                aux = j;
        }   
        return aux;
    }
    //********************************************************
    // FROM GUI
    //********************************************************

    @Override
    public void processConnection (String name){
        try { 
            model = new Model(new LocalUser(name, getLocalHost().getHostAddress()));
        } catch (UnknownHostException ex) {
            Logger.getLogger(Presenter.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.n.unblockNI();
        //n.launchNI();
        this.n.performHello();
    }
    
    @Override
    public void processDeconnection(){
        this.n.blockNI();
        this.n.performGoodbye();
        model = null;
    }

    @Override
    public void processMessageToSend(String texte, RemoteUser remote_user){ //ajouter le destinataire
        this.n.performSend(texte,remote_user);
    }
    
    @Override
    public void processEnvoieFichier(File file, RemoteUser remote_user){
        this.waitToSend.add(file);
        this.n.performFileRequest(file.getName(), remote_user);
        
                }    
    @Override
    public boolean processAccordFichier(String file_name, RemoteUser remote_user){
        return true;
    }    
    
    public void performRemoteUserAcceptedFile(boolean accord, String file_name, RemoteUser remote_user){
        if (accord) {
            System.out.println("----file: "+file_name+" accepted" );
            this.n.performFileSend(fileWaiting(file_name), remote_user);
            //Write on the window file sended
        }
        else {fileWaiting(file_name).delete(); 
System.out.println("Negative answer for dowload: "+file_name);
//Write on the window file refused

    } 
        gui.processFileSending(remote_user, file_name,accord);
    }
    
    //********************************************************
    // FROM NI
    //********************************************************
    
    @Override
    public void processHello(Hello m, String remoteAddr){
        System.out.println("Hello reçu  "+m.toString());
        RemoteUser r = new RemoteUser(m.getNickname(), remoteAddr);
        try {
            if(!(remoteAddr.equals(getLocalHost().getHostAddress())))
            {
                model.addRemoteUser(r);
                gui.processRemoteUserConnection(r);
            }
        } catch (UnknownHostException ex) {
            Logger.getLogger(Presenter.class.getName()).log(Level.SEVERE, null, ex);
        }
        n.performHelloAck(r);
    }
    
    @Override
    public void processHelloAck(HelloAck m, String remoteAddr){
        System.out.println("Hello ack reçu  "+m.toString());
        RemoteUser r = new RemoteUser(m.getNickname(), remoteAddr);
        model.addRemoteUser(r);
        gui.processRemoteUserConnection(r);
    }
    
    @Override
    public void processSend(Send m, String remoteAddr){
        gui.processMessageReception(model.checkRemoteUser(remoteAddr), m.getMessage());
    }
    
    @Override
    public void processGoodbye(Goodbye m, String remoteAddr) {
        System.out.println("Goodbye reçu  "+m.toString());
        RemoteUser r = model.checkRemoteUser(remoteAddr);
        try {
            if(!(remoteAddr.equals(getLocalHost().getHostAddress())))
                model.delRemoteUser(r);
        } catch (UnknownHostException ex) {
            Logger.getLogger(Presenter.class.getName()).log(Level.SEVERE, null, ex);
        }
        gui.processRemoteUserDeconnection(r);
    }  
    
    ////////////////////////////////
    
    public void processFileRequest(FileRequest m, String remoteAddr) throws IOException {
        System.out.println("File request reçu  "+m.toString());
        boolean accord;
        accord = gui.processRemoteUserFileRequest(model.checkRemoteUser(remoteAddr), m.getName());
        if (accord){
            n.performFileReceive(m.getName());
            
            
            
        }
        n.performFileResponse(accord, m.getName(), model.checkRemoteUser(remoteAddr));
        gui.processFileReception(model.checkRemoteUser(remoteAddr), m.getName(), accord);
           
       
    }
    
    public void processFileResponse(FileResponse m, String remoteAddr) {
        boolean accord = m.getResponse();
        System.out.println("File response reçu  "+m.toString());
        performRemoteUserAcceptedFile(accord,m.getName(), model.checkRemoteUser(remoteAddr));
    }
    
}
